package gui.actions;

import gui.GuiManager;
import gui.GuiManager.FramesEnum;
import gui.components.AntiAliasedLabel;
import gui.models.PlayModel;

import javax.swing.BorderFactory;
import javax.swing.JOptionPane;

import common.enums.AnswerEnum;
import common.interfaces.PlayInterface;
import common.types.Pair;
import common.utils.CommonUtils;

@SuppressWarnings("serial")
public class PlayAction extends WorkerAction {

	private static boolean isGameStarted;
	private final PlayModel model;
	private PlayInterface playLogic;
	
	public PlayAction(PlayModel model) {
		super();
		this.model = model;
		this.playLogic = model.getPlayLogic();
		isGameStarted = false;
	}
	
	@Override
	public boolean isAllowToRunOperation() {
		if (model.isGuessed() && !model.isSubmitedGuess()) {
			if (!model.isCorrectGuess()) {
				String enteredName;
				boolean isValid = true;
				do {
					if (!isValid) {
						String errorMsg = "Must enter a name in english that is not empty and not longer then 63 char's";
						JOptionPane.showMessageDialog(getOwner(), errorMsg, "Invalid name", JOptionPane.ERROR_MESSAGE);
					}
					
	                AntiAliasedLabel label = new AntiAliasedLabel("Enter the name of the character you chose:",14);
	                label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
					enteredName = (String)JOptionPane.showInputDialog(
	                		getOwner(),
	                        label,
	                        "Submit",
	                        JOptionPane.PLAIN_MESSAGE,
	                        null,
	                        null,
	                        "Enter here...");
					
					isValid = enteredName == null || (!enteredName.isEmpty() && enteredName.length()<=63 && CommonUtils.isValidAscii(enteredName));			
				} while (!isValid);
				model.setEnteredActual(enteredName);
			}
		}
		return true;
	}
	
	@Override
	public void runOperation() throws Exception {
		if (!isGameStarted) {
			playLogic.startGame();
			model.resetModel();
			isGameStarted = true;
		} else if (!model.isGuessed()) {
			playLogic.submitAnswer(new Pair<Integer, AnswerEnum>(model.getNextQuestion().getLeft(), model.getAnswer()));
		}
		if (model.isGuessed()) {
			if (model.isCorrectGuess() || model.isEnteredActual()) {
				Pair<Boolean, String> actualGuess = new Pair<Boolean, String>(model.isCorrectGuess(), model.getActual());
				playLogic.submitActualGuess(actualGuess);
			}
			model.setIsSubmitedGuess(true);
		} else {
			model.setIsGuessed(playLogic.isGuessed());			
		}
		if (model.isGuessed()) {
			if (model.isSubmitedGuess()) {
				playLogic.finishGame();
				isGameStarted = false;	
			} else {
				model.setGuess(playLogic.getGuess());
			}
		} else {		
			model.setNextQuestion(playLogic.getNextQuestion());
		}
	}
	
	@Override
	public void operationSucceed() {
		model.notifyObservers();
	}
	
	@Override
	public void operationFailed(Exception e) {
		String errorMsg = "There was an error with the game and the current game session must terminate.\nThe following error occured: " + e.getLocalizedMessage();
		String errorTitle = "Game Error";
		JOptionPane.showMessageDialog(getOwner(), errorMsg, errorTitle, JOptionPane.ERROR_MESSAGE);
	}
	
	@Override
	public boolean isAllowToRunCommitOperation() {
		return isOperationFailed();
	}
	
	@Override
	public void runCommitOperation() throws Exception {
		playLogic.finishGame();
	}
	
	@Override
	public void commitOperationSucceed() {
		GuiManager.switchFrame(FramesEnum.PREVIOUS_FRAME);
		isGameStarted = false;
	}
	
	@Override
	public void commitOperationFailed(Exception e) {
		String majorErrorMsg = "A major error occured, must shut down game.\nThe following error occured: " + e.getLocalizedMessage();
		String majorErrorTitle = "Major Error";
		JOptionPane.showMessageDialog(getOwner(), majorErrorMsg, majorErrorTitle, JOptionPane.ERROR_MESSAGE);
		GuiManager.quitApplication();
	}

}
